[OpenCV] ArUcoマーカーを使用して、売り切れ商品を検出してみました。
1 はじめに
CX事業本部の平内(SIN)です。
店舗の商品監視をターゲットに、OpenCVを利用した撮影について、数日前から試してきました。
[OpenCV] ArUcoマーカーを使用して、安定した商品の監視映像を撮影してみました。
[OpenCV] 一定期間動かないものだけを撮影する
今回は、上記の簡単な拡張として、ArUcoマーカーで売り切れ商品の検出を試してみました。
最初に、動作しているようすです。
左の画面が、Webカメラで撮影した映像そのままで、右の画面が、その一部を監視している画面です。 監視の画面では、緑の枠で商品の位置を認識しており、全部無くなってしまうと、棚に貼ってある「近日入荷予定シール」に着いているマーカーを検出し、赤枠表示にしています。
2 近日入荷予定
商品が全てなくなった時見えるように、「近日入荷予定シール」が張っています。これは、マーカーを一緒に印刷して、貼っているだけです。
このマーカーは、id=0であり、各商品の上に配置しているマーカーや、四隅の基準となるマーカーとは、idが異なりますが、「近日入荷予定シール」は、いづれの商品でも同じです。
下図のように、各商品のマーカー位置を基準に、商品が有るべき位置を計算して(細線の緑枠)、その中にid=0のマーカーが存在するかどうかで、売り切れの判定(太線の)が行われます。
3 コード
監視エリア内で、商品の位置を計算し、「近日入荷予定シール」を検出しているコードは、以下の通りです。
# 品切れの検知 def confirmSoldOut(frame, dictionary): # マーカーから商品まで距離 margin = 50 # 一つの商品のサイズ width = 300 height = 420 # 描画領域の座標系でマーカーを取得する corners, ids, rejectedImgPoints = aruco.detectMarkers(frame, dictionary) # index=15,16,17のマーカーを検出する for index in [15,16,17]: # マーカーの中心を取得 marker = getMarkerMean(ids, corners, index) if(marker!=None): # マーカーの中心座標から商品のエリアを算出する x = marker[0] y = marker[1] x1 = int(x-(width/2)) y1 = int(y+margin) x2 = int(x+(width/2)) y2 = int(y+height+margin) # 商品エリアの中に、index=0(売り切れ)マーカーが存在するかどうか確認 isSoldOut = False for (i,id) in enumerate(ids): if(id[0]==0): v = np.mean(corners[i][0],axis=0) if(x1 < v[0] and v[0] < x2 and y1 < v[1] and v[1] < y2): isSoldOut = True # 売り切れの場合に、赤枠を表示する if(isSoldOut): frame = cv2.rectangle(frame, (x1, y1), (x2, y2),(0,0,255),5) else: frame = cv2.rectangle(frame, (x1, y1), (x2, y2),(0,255,0),1) return frame
上記以外については、先のブログと同じなので、ここでは、省略させて下さい。
参考:[OpenCV] ArUcoマーカーを使用して、安定した商品の監視映像を撮影してみました。
4 最後に
今回は、「近日入荷予定シール」を検出しても、赤枠を表示しているだけですが、これをトリガーに、スタッフへの通知や、在庫調整に繋げることも可能かもしれません。